package com.xjrh.traintravel.collector.netty;

import com.xjrh.common.core.utils.DateUtils;
import com.xjrh.traintravel.collector.netty.handler.AccessAgreementHandler;
import com.xjrh.traintravel.collector.netty.handler.BaseAgreementHandler;
import com.xjrh.traintravel.collector.runner.NettyClientManager;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;

/**
 * 服务端心跳检测Trigger
 * s
 * @author snps
 * @create 2022-01-17 16:20
 * @describe
 **/
@Component
@ChannelHandler.Sharable
@Slf4j
public class ServerIdleStateTrigger extends ChannelInboundHandlerAdapter {

    @Resource
    private AccessAgreementHandler accessAgreementHandler;

    @Resource
    private NettyClientManager nettyClientManager;


    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) evt).state();
            String eventType = null;

            switch (state){
                case READER_IDLE:
                    eventType = "读空闲";
                    break;
                case WRITER_IDLE:
                    eventType = "写空闲";
                    break;
                case ALL_IDLE:
                    eventType ="读写空闲";
                    break;
            }

            log.error("客户端：{} 发生 {}", ctx.channel().remoteAddress(), eventType);
            // 通过“客户端最近通信时间”，判断是否需要“移除客户端连接”。移除标准：心跳周期(30秒) * 3
            String equipmentId = accessAgreementHandler.getClientChannelKey(ctx.channel());
            /*Date equipmentLatelyActiveTime = nettyClientManager.getClientChannelTime(equipmentId);
            if (equipmentLatelyActiveTime != null) {
                Date now = new Date();
                long timeoutSecond = DateUtils.getDatetimeDifference(equipmentLatelyActiveTime, now);
                if (timeoutSecond >= ServerChannelInitializer.CLIENT_TIMEOUT_SECOND) {
                    log.error("最近通讯时间：{}，检测超时时间：{}，超时时间：{}秒", DateUtils.getDate2String(equipmentLatelyActiveTime, DateUtils.YYYY_MM_DD_HH_MM_SS),
                            DateUtils.getDate2String(now, DateUtils.YYYY_MM_DD_HH_MM_SS), timeoutSecond);
                    // 移除客户端连接
                    accessAgreementHandler.removeClientChannel(equipmentId);
                } else {
                    // 客户端连接出现读写超时，但客户端实际通讯时间小于规定指定超时时间
                    AttributeKey<String> attrEquipmentId = AttributeKey.valueOf(BaseAgreementHandler.ATTR_KEY_EQUIPMENT_ID);
                    ctx.channel().attr(attrEquipmentId).remove();
                }
            }*/

            // 移除客户端连接
            accessAgreementHandler.removeClientChannel(equipmentId);
            ctx.channel().close();
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

}